2 Additional tools for Minizip
3 Code: Xavier Roche '2004
4 License: Same as ZLIB (www.gzip.org)
11 #include "ZLIB/zlib.h"
14 #define READ_8(adr) ((unsigned char)*(adr))
15 #define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) )
16 #define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) )
18 #define WRITE_8(buff, n) do { \
19 *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \
21 #define WRITE_16(buff, n) do { \
22 WRITE_8((unsigned char*)(buff), n); \
23 WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \
25 #define WRITE_32(buff, n) do { \
26 WRITE_16((unsigned char*)(buff), (n) & 0xffff); \
27 WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \
30 extern int ZEXPORT
unzRepair(file
, fileOut
, fileOutTmp
, nRecovered
, bytesRecovered
)
33 const char* fileOutTmp
;
35 uLong
* bytesRecovered
;
38 FILE* fpZip
= fopen(file
, "rb");
39 FILE* fpOut
= fopen(fileOut
, "wb");
40 FILE* fpOutCD
= fopen(fileOutTmp
, "wb");
41 if (fpZip
!= NULL
&& fpOut
!= NULL
) {
49 while ( fread(header
, 1, 30, fpZip
) == 30 ) {
50 int currentOffset
= offset
;
53 if (READ_32(header
) == 0x04034b50) {
54 unsigned int version
= READ_16(header
+ 4);
55 unsigned int gpflag
= READ_16(header
+ 6);
56 unsigned int method
= READ_16(header
+ 8);
57 unsigned int filetime
= READ_16(header
+ 10);
58 unsigned int filedate
= READ_16(header
+ 12);
59 unsigned int crc
= READ_32(header
+ 14); /* crc */
60 unsigned int cpsize
= READ_32(header
+ 18); /* compressed size */
61 unsigned int uncpsize
= READ_32(header
+ 22); /* uncompressed sz */
62 unsigned int fnsize
= READ_16(header
+ 26); /* file name length */
63 unsigned int extsize
= READ_16(header
+ 28); /* extra field length */
64 filename
[0] = extra
[0] = '\0';
67 if (fwrite(header
, 1, 30, fpOut
) == 30) {
76 if (fread(filename
, 1, fnsize
, fpZip
) == fnsize
) {
77 if (fwrite(filename
, 1, fnsize
, fpOut
) == fnsize
) {
94 if (fread(extra
, 1, extsize
, fpZip
) == extsize
) {
95 if (fwrite(extra
, 1, extsize
, fpOut
) == extsize
) {
109 int dataSize
= cpsize
;
114 char* data
= malloc(dataSize
);
116 if ((int)fread(data
, 1, dataSize
, fpZip
) == dataSize
) {
117 if ((int)fwrite(data
, 1, dataSize
, fpOut
) == dataSize
) {
119 totalBytes
+= dataSize
;
137 /* Central directory entry */
141 int comsize
= (int) strlen(comment
);
142 WRITE_32(header
, 0x02014b50);
143 WRITE_16(header
+ 4, version
);
144 WRITE_16(header
+ 6, version
);
145 WRITE_16(header
+ 8, gpflag
);
146 WRITE_16(header
+ 10, method
);
147 WRITE_16(header
+ 12, filetime
);
148 WRITE_16(header
+ 14, filedate
);
149 WRITE_32(header
+ 16, crc
);
150 WRITE_32(header
+ 20, cpsize
);
151 WRITE_32(header
+ 24, uncpsize
);
152 WRITE_16(header
+ 28, fnsize
);
153 WRITE_16(header
+ 30, extsize
);
154 WRITE_16(header
+ 32, comsize
);
155 WRITE_16(header
+ 34, 0); /* disk # */
156 WRITE_16(header
+ 36, 0); /* int attrb */
157 WRITE_32(header
+ 38, 0); /* ext attrb */
158 WRITE_32(header
+ 42, currentOffset
);
160 if (fwrite(header
, 1, 46, fpOutCD
) == 46) {
165 if (fwrite(filename
, 1, fnsize
, fpOutCD
) == fnsize
) {
172 err
= Z_STREAM_ERROR
;
178 if (fwrite(extra
, 1, extsize
, fpOutCD
) == extsize
) {
188 if ((int)fwrite(comment
, 1, comsize
, fpOutCD
) == comsize
) {
211 /* Final central directory */
213 int entriesZip
= entries
;
215 char* comment
= ""; // "ZIP File recovered by zlib/minizip/mztools";
216 int comsize
= (int) strlen(comment
);
217 if (entriesZip
> 0xffff) {
220 WRITE_32(header
, 0x06054b50);
221 WRITE_16(header
+ 4, 0); /* disk # */
222 WRITE_16(header
+ 6, 0); /* disk # */
223 WRITE_16(header
+ 8, entriesZip
); /* hack */
224 WRITE_16(header
+ 10, entriesZip
); /* hack */
225 WRITE_32(header
+ 12, offsetCD
); /* size of CD */
226 WRITE_32(header
+ 16, offset
); /* offset to CD */
227 WRITE_16(header
+ 20, comsize
); /* comment */
230 if (fwrite(header
, 1, 22, fpOutCD
) == 22) {
234 if ((int)fwrite(comment
, 1, comsize
, fpOutCD
) != comsize
) {
244 /* Final merge (file + central directory) */
247 fpOutCD
= fopen(fileOutTmp
, "rb");
248 if (fpOutCD
!= NULL
) {
251 while ( (nRead
= (int)fread(buffer
, 1, sizeof(buffer
), fpOutCD
)) > 0) {
252 if ((int)fwrite(buffer
, 1, nRead
, fpOut
) != nRead
) {
265 /* Wipe temporary file */
266 (void)remove(fileOutTmp
);
268 /* Number of recovered entries */
270 if (nRecovered
!= NULL
) {
271 *nRecovered
= entries
;
273 if (bytesRecovered
!= NULL
) {
274 *bytesRecovered
= totalBytes
;
278 err
= Z_STREAM_ERROR
;